<template>
  <a-modal
    v-model:open="visible"
    :mask-closable="false"
    width="85%"
    title="修改"
    :style="{ top: '20px' }"
  >
    <div class="app-card-container">
      <div v-loading="loading" v-permission="['base-data:product:info:modify']">
        <a-form
          ref="form"
          :label-col="{ span: 6 }"
          :wrapper-col="{ span: 14 }"
          :model="formData"
          :rules="rules"
        >
          <a-row v-if="$enums.PRODUCT_TYPE.SPEC.equalsCode(productType)">
            <a-col :md="8" :sm="24">
              <a-form-item label="编号" name="code">
                <a-input-group compact>
                  <a-input
                    v-model:value.trim="formData.code"
                    style="width: calc(100% - 75px)"
                    disabled
                  />
                </a-input-group>
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="名称" name="name">
                <a-input v-model:value="formData.name" allow-clear />
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="简称" name="shortName">
                <a-input v-model:value="formData.shortName" allow-clear />
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="简码" name="externalCode">
                <a-input v-model:value="formData.externalCode" allow-clear />
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="商品分类" name="categoryId">
                <product-category-selector
                  v-model:value="formData.categoryId"
                  :request-params="{ available: true, categoryTypes: categoryTypes }"
                  :only-final="false"
                  @update:value="selectCategory"
                />
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="商品品牌" name="brandId">
                <product-brand-selector
                  v-model:value="formData.brandId"
                  :request-params="{ available: true }"
                />
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="单位" name="unit" required>
                <unit-selector v-model:value="formData.unit" />
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="归属门店" name="shopId">
                <span v-if="$utils.isEmpty(formData.shopId)">总部</span>
                <shop-selector v-else v-model:value="formData.shopId" readOnly />
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="进项税率（%）" name="taxRate">
                <a-input v-model:value="formData.taxRate" allow-clear />
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="销项税率（%）" name="saleTaxRate">
                <a-input v-model:value="formData.saleTaxRate" allow-clear />
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="保质期（天）" name="expiryDay">
                <a-input-number v-model:value="formData.expiryDay" allow-clear />
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="商品图片" name="imageUrl">
                <JImgUpload v-model:value="formData.imageUrl" />
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="商品介绍" name="introduction">
                <a-textarea
                  v-model:value="formData.introduction"
                  :auto-size="{ minRows: 2, maxRows: 5 }"
                  allow-clear
                />
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="状态" name="available">
                <a-select
                  v-model:value="formData.available"
                  @change="(value) => batchSettingConfirm('available', value)"
                  allow-clear
                >
                  <a-select-option
                    v-for="item in $enums.AVAILABLE.values()"
                    :key="item.code"
                    :value="item.code"
                  >
                    {{ item.desc }}
                  </a-select-option>
                </a-select>
              </a-form-item>
            </a-col>
          </a-row>
          <a-row
            v-if="
              $enums.PRODUCT_TYPE.NORMAL.equalsCode(productType) ||
              $enums.PRODUCT_TYPE.BUNDLE.equalsCode(productType)
            "
          >
            <a-col :md="8" :sm="24">
              <a-form-item label="编号" name="code">
                <a-input v-model:value="formData.code" disabled allow-clear />
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="名称" name="name">
                <a-input v-model:value="formData.name" allow-clear />
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="简称" name="shortName">
                <a-input v-model:value="formData.shortName" allow-clear />
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="SKU编号" name="skuCode">
                <a-input v-model:value="formData.skuCode" disabled allow-clear />
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="简码" name="externalCode">
                <a-input v-model:value="formData.externalCode" allow-clear />
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="商品分类" name="categoryId">
                <product-category-selector
                  v-model:value="formData.categoryId"
                  :request-params="{ available: true, categoryTypes: categoryTypes }"
                  :only-final="false"
                  @update:value="selectCategory"
                />
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="商品品牌" name="brandId">
                <product-brand-selector
                  v-model:value="formData.brandId"
                  :request-params="{ available: true }"
                />
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="规格" name="spec" required>
                <a-input v-model:value="formData.spec" allow-clear />
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="单位" name="unit" required>
                <unit-selector v-model:value="formData.unit" />
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="归属门店" name="shopId">
                <span v-if="$utils.isEmpty(formData.shopId)">总部</span>
                <shop-selector v-else v-model:value="formData.shopId" readOnly />
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="商品图片" name="imageUrl">
                <JImgUpload v-model:value="formData.imageUrl" />
              </a-form-item>
            </a-col>
            <a-col v-if="$enums.PRODUCT_TYPE.NORMAL.equalsCode(productType)" :md="8" :sm="24">
              <a-form-item label="重量（kg）" name="weight">
                <a-input v-model:value="formData.weight" allow-clear />
              </a-form-item>
            </a-col>
            <a-col v-if="$enums.PRODUCT_TYPE.NORMAL.equalsCode(productType)" :md="8" :sm="24">
              <a-form-item label="体积（cm³）" name="volume">
                <a-input v-model:value="formData.volume" allow-clear />
              </a-form-item>
            </a-col>
            <a-col v-if="$enums.PRODUCT_TYPE.NORMAL.equalsCode(productType)" :md="8" :sm="24">
              <a-form-item label="进项税率（%）" name="taxRate">
                <a-input v-model:value="formData.taxRate" allow-clear />
              </a-form-item>
            </a-col>
            <a-col v-if="$enums.PRODUCT_TYPE.NORMAL.equalsCode(productType)" :md="8" :sm="24">
              <a-form-item label="销项税率（%）" name="saleTaxRate">
                <a-input v-model:value="formData.saleTaxRate" allow-clear />
              </a-form-item>
            </a-col>
            <a-col v-if="$enums.PRODUCT_TYPE.NORMAL.equalsCode(productType)" :md="8" :sm="24">
              <a-form-item label="采购价（元）" name="purchasePrice">
                <a-input v-model:value="formData.purchasePrice" allow-clear />
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="销售价（元）" name="salePrice">
                <a-input-group compact>
                  <a-input
                    v-model:value="formData.salePrice"
                    style="width: calc(100% - 55px)"
                    allow-clear
                  />
                  <a-button
                    type="primary"
                    @click="() => (formData.salePrice = calculatePrice('salePrice'))"
                    :disabled="![2].includes(formData.productType)"
                  >
                    计算
                  </a-button>
                </a-input-group>
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="零售价（元）" name="retailPrice">
                <a-input-group compact>
                  <a-input
                    v-model:value="formData.retailPrice"
                    style="width: calc(100% - 55px)"
                    allow-clear
                  />
                  <a-button
                    type="primary"
                    @click="() => (formData.retailPrice = calculatePrice('retailPrice'))"
                    :disabled="![2].includes(formData.productType)"
                  >
                    计算
                  </a-button>
                </a-input-group>
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="保质期（天）" name="expiryDay">
                <a-input-number v-model:value="formData.expiryDay" allow-clear />
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="状态" name="available">
                <a-select v-model:value="formData.available" allow-clear>
                  <a-select-option
                    v-for="item in $enums.AVAILABLE.values()"
                    :key="item.code"
                    :value="item.code"
                  >
                    {{ item.desc }}
                  </a-select-option>
                </a-select>
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="商品介绍" name="introduction">
                <a-textarea
                  v-model:value="formData.introduction"
                  :auto-size="{ minRows: 2, maxRows: 5 }"
                  allow-clear
                />
              </a-form-item>
            </a-col>
          </a-row>
          <a-row>
            <a-col v-for="modelor in modelorList" :key="modelor.id" :md="8" :sm="24">
              <a-form-item :label="modelor.name" :required="modelor.isRequired">
                <a-select
                  v-if="$enums.COLUMN_TYPE.MULTIPLE.equalsCode(modelor.columnType)"
                  v-model:value="modelor.text"
                  mode="multiple"
                  placeholder="请选择"
                >
                  <a-select-option v-for="item in modelor.items" :key="item.id" :value="item.id">{{
                    item.name
                  }}</a-select-option>
                </a-select>
                <a-select
                  v-if="$enums.COLUMN_TYPE.SINGLE.equalsCode(modelor.columnType)"
                  v-model:value="modelor.text"
                  placeholder="请选择"
                >
                  <a-select-option v-for="item in modelor.items" :key="item.id" :value="item.id">{{
                    item.name
                  }}</a-select-option>
                </a-select>
                <div v-else-if="$enums.COLUMN_TYPE.CUSTOM.equalsCode(modelor.columnType)">
                  <a-input-number
                    v-if="$enums.COLUMN_DATA_TYPE.INT.equalsCode(modelor.columnDataType)"
                    v-model:value="modelor.text"
                    class="number-input"
                  />
                  <a-input-number
                    v-else-if="$enums.COLUMN_DATA_TYPE.FLOAT.equalsCode(modelor.columnDataType)"
                    v-model:value="modelor.text"
                    :precision="2"
                    class="number-input"
                  />
                  <a-input
                    v-else-if="$enums.COLUMN_DATA_TYPE.STRING.equalsCode(modelor.columnDataType)"
                    v-model:value="modelor.text"
                  />
                  <a-date-picker
                    v-else-if="$enums.COLUMN_DATA_TYPE.DATE.equalsCode(modelor.columnDataType)"
                    v-model:value="modelor.text"
                    placeholder=""
                    value-format="YYYY-MM-DD"
                  />
                  <a-time-picker
                    v-else-if="$enums.COLUMN_DATA_TYPE.TIME.equalsCode(modelor.columnDataType)"
                    v-model:value="modelor.text"
                    placeholder=""
                    value-format="HH:mm:ss"
                  />
                  <a-date-picker
                    v-else-if="$enums.COLUMN_DATA_TYPE.DATE_TIME.equalsCode(modelor.columnDataType)"
                    v-model:value="modelor.text"
                    placeholder=""
                    show-time
                    value-format="YYYY-MM-DD HH:mm:ss"
                  />
                </div>
              </a-form-item>
            </a-col>
          </a-row>
          <a-row v-if="$enums.PRODUCT_TYPE.BUNDLE.equalsCode(productType)">
            <a-col :span="24">
              <vxe-grid
                ref="grid"
                resizable
                show-overflow
                highlight-hover-row
                keep-source
                row-id="id"
                height="500"
                :data="productBundles"
                :columns="[
                  { type: 'checkbox', width: 45 },
                  {
                    field: 'product',
                    title: '单品',
                    minWidth: 260,
                    slots: { default: 'product_default' },
                  },
                  {
                    field: 'spec',
                    title: '规格',
                    width: 140,
                  },
                  {
                    field: 'bundle_num',
                    title: '包含数量',
                    width: 200,
                    align: 'right',
                    slots: { default: 'bundleNum_default', header: 'bundleNum_header' },
                  },
                  {
                    field: 'salePrice',
                    title: '销售价（元）',
                    width: 200,
                    align: 'right',
                    slots: { default: 'salePrice_default', header: 'salePrice_header' },
                  },
                  {
                    field: 'retailPrice',
                    title: '零售价（元）',
                    width: 200,
                    align: 'right',
                    slots: { default: 'retailPrice_default', header: 'retailPrice_header' },
                  },
                ]"
                :toolbar-config="{
                  // 缩放
                  zoom: false,
                  // 自定义表头
                  custom: false,
                  // 右侧是否显示刷新按钮
                  refresh: false,
                  // 自定义左侧工具栏
                  slots: {
                    buttons: 'toolbar_buttons',
                  },
                }"
              >
                <!-- 工具栏 -->
                <template #toolbar_buttons>
                  <a-space>
                    <a-button type="primary" :icon="h(PlusOutlined)" @click="addRow">新增</a-button>
                    <a-button danger :icon="h(DeleteOutlined)" @click="delRow">删除</a-button>
                  </a-space>
                </template>

                <!-- 商品 列自定义内容 -->
                <template #product_default="{ row }">
                  <product-selector
                    v-model:value="row.productId"
                    :request-params="{
                      shopId: formData.shopId,
                      productType: [1, 4].join(','),
                    }"
                    @input-row="
                      (data) => {
                        row.spec = data.spec;
                        row.salePrice = data.salePrice;
                        row.retailPrice = data.retailPrice;
                      }
                    "
                    @load-complete="
                      (data) => {
                        $nextTick(() => {
                          row.spec = data[0]?.spec;
                        });
                      }
                    "
                  />
                </template>

                <!-- 包含数量 列自定义表头 -->
                <template #bundleNum_header>
                  <a-space>
                    <span>包含数量</span>
                    <a-tooltip title="表示一个组合商品中包含的单品数量">
                      <a-button type="link" :icon="h(InfoCircleOutlined)" />
                    </a-tooltip>
                  </a-space>
                </template>

                <!-- 包含数量 列自定义内容 -->
                <template #bundleNum_default="{ row }">
                  <a-input v-model:value="row.bundleNum" class="number-input" />
                </template>

                <!-- 销售价 列自定义表头 -->
                <template #salePrice_header>
                  <a-space>
                    <span>销售价（元）</span>
                    <a-tooltip
                      title="表示一个组合商品销售后的单品的销售价，此处的计算公式：每行单品的【包含数量】乘以【销售价】的总和 等于【组合商品的销售价】"
                    >
                      <a-button type="link" :icon="h(InfoCircleOutlined)" />
                    </a-tooltip>
                  </a-space>
                </template>

                <!-- 销售价 列自定义内容 -->
                <template #salePrice_default="{ row }">
                  <a-input v-model:value="row.salePrice" class="number-input" />
                </template>

                <!-- 零售价 列自定义表头 -->
                <template #retailPrice_header>
                  <a-space>
                    <span>零售价（元）</span>
                    <a-tooltip
                      title="表示一个组合商品零售后的单品的零售价，此处的计算公式：每行单品的【包含数量】乘以【零售价】的总和 等于【组合商品的零售价】"
                    >
                      <a-button type="link" :icon="h(InfoCircleOutlined)" />
                    </a-tooltip>
                  </a-space>
                </template>

                <!-- 零售价 列自定义内容 -->
                <template #retailPrice_default="{ row }">
                  <a-input v-model:value="row.retailPrice" class="number-input" />
                </template>
              </vxe-grid>
            </a-col>
          </a-row>
          <a-row v-if="$enums.PRODUCT_TYPE.SPEC.equalsCode(productType) && modelorList?.length > 0">
            <a-col :span="24">
              <vxe-grid
                ref="specGrid"
                resizable
                show-overflow
                highlight-hover-row
                keep-source
                row-id="id"
                height="500"
                :data="formData.productData"
                :columns="tableColumn"
                :checkbox-config="{
                  checkMethod: ({ row }) => {
                    return !row.specId;
                  },
                }"
                :toolbar-config="{
                  zoom: false,
                  custom: false,
                  refresh: false,
                  slots: {
                    buttons: 'toolbar_buttons',
                  },
                }"
              >
                <!-- 工具栏 -->
                <template #toolbar_buttons>
                  <a-space>
                    <a-button type="primary" @click="addSpec(true)">新增</a-button>
                    <a-button type="primary" @click="generateSpec()">批量生成规格</a-button>
                    <a-button class="c-button-success" type="ghost" @click="selectGenerateSpec()">
                      自定义生成规格
                    </a-button>
                    <a-button :icon="h(DeleteOutlined)" @click="batchDeleteSpec" danger>
                      删除
                    </a-button>
                  </a-space>
                </template>
                <!-- 批量设置表头 -->
                <template #setting_header="{ column }">
                  <a-space :size="0">
                    <span>{{ column.title }}</span>
                    <span>
                      <a-button
                        type="link"
                        :icon="h(EditOutlined)"
                        @click.prevent.stop="
                          () => {
                            $refs.batchSetting.openDialog(column.field, column.type, column.title);
                          }
                        "
                      />
                    </span>
                  </a-space>
                </template>
                <!-- 规格属性值 列自定义内容 -->
                <template #propertyValue_default="{ columnIndex, column, rowIndex, row }">
                  <a-form-item
                    :name="['productData', rowIndex, 'property', columnIndex - 1, 'propertyItemId']"
                    :rules="[{ required: true, message: '请选择属性值' }]"
                    no-style
                  >
                    <a-select
                      :value="row.property[columnIndex - 1]?.propertyItemId"
                      :placeholder="`请选择${column.title}`"
                      @change="(value) => propertyValueChange(columnIndex - 1, row, value)"
                      allow-clear
                    >
                      <a-select-option
                        v-for="item in modelorList.find((p) => p.id === column.field)?.items || []"
                        :key="item.id"
                        :value="item.id"
                      >
                        {{ item.name }}
                      </a-select-option>
                    </a-select>
                  </a-form-item>
                </template>
                <!-- 规格名称 列自定义内容 -->
                <template #spec_default="{ column, rowIndex, row }">
                  <a-form-item
                    :name="['productData', rowIndex, column.field]"
                    :rules="[{ required: true, message: '请输入' + column.title }]"
                    no-style
                  >
                    <a-input-group compact>
                      <a-input
                        v-model:value="row[column.field]"
                        style="width: calc(100% - 47px)"
                        allow-clear
                      />
                      <a-button type="primary" @click="() => onGenerateSpec(row)"> 生成 </a-button>
                    </a-input-group>
                  </a-form-item>
                </template>
                <!-- sku编号 列自定义内容 -->
                <template #sku_default="{ column, rowIndex, row }">
                  <span v-if="row.specId">
                    {{ row[column.field] || '' }}
                  </span>
                  <a-form-item
                    v-else
                    :name="['productData', rowIndex, column.field]"
                    :rules="[{ required: true, message: '请输入SKU' }]"
                    no-style
                  >
                    <a-input-group compact>
                      <a-input
                        v-model:value="row[column.field]"
                        style="width: calc(100% - 70px)"
                        allow-clear
                      />
                      <a-button type="primary" @click="() => onGenerateSkuCode(row)">
                        点此生成
                      </a-button>
                    </a-input-group>
                  </a-form-item>
                </template>
                <!-- 单位 列自定义内容 -->
                <template #unit_default="{ column, rowIndex, row }">
                  <a-form-item
                    :name="['productData', rowIndex, column.field]"
                    :rules="[{ required: true, message: '请选择单位' }]"
                    no-style
                  >
                    <unit-selector v-model:value="row[column.field]" />
                  </a-form-item>
                </template>
                <!-- 价格 列自定义内容 -->
                <template #price_default="{ column, rowIndex, row }">
                  <a-form-item
                    :name="['productData', rowIndex, column.field]"
                    :rules="[{ required: true, message: '请输入价格' }]"
                    no-style
                  >
                    <a-input-number v-model:value="row[column.field]" :precision="2" min="0" />
                  </a-form-item>
                </template>
                <!-- 数量 列自定义内容 -->
                <template #number_default="{ column, rowIndex, row }">
                  <a-form-item :name="['productData', rowIndex, column.field]" no-style>
                    <a-input-number v-model:value="row[column.field]" :precision="2" min="0" />
                  </a-form-item>
                </template>
                <template #available_default="{ column, rowIndex, row }">
                  <a-form-item
                    :name="['productData', rowIndex, column.field]"
                    :rules="[{ required: true, message: '请输入数量' }]"
                    no-style
                  >
                    <a-select v-model:value="row[column.field]" allow-clear>
                      <a-select-option
                        v-for="item in $enums.AVAILABLE.values()"
                        :key="item.code"
                        :value="item.code"
                      >
                        {{ item.desc }}
                      </a-select-option>
                    </a-select>
                  </a-form-item>
                </template>
                <!-- 删除按钮 -->
                <template #action_default="{ rowIndex, row }">
                  <a-space>
                    <a-button @click="delSpec(rowIndex)" :disabled="row.specId" danger>
                      删除
                    </a-button>
                  </a-space>
                </template>
              </vxe-grid>
            </a-col>
          </a-row>
        </a-form>
      </div>
    </div>
    <template #footer>
      <div class="form-modal-footer">
        <a-space>
          <a-button type="primary" @click="submit">保存</a-button>
          <a-button @click="closeDialog">关闭</a-button>
        </a-space>
      </div>
    </template>
  </a-modal>
  <select-gen-spec ref="selectGenSpecRef" :modelor-list="modelorList" @confirm="onSelectGenSpec" />
  <batch-setting ref="batchSetting" @confirm="batchSettingConfirm" />
</template>
<script>
  import {
    PlusOutlined,
    DeleteOutlined,
    EditOutlined,
    InfoCircleOutlined,
  } from '@ant-design/icons-vue';
  import { defineComponent, h } from 'vue';
  import { validCode } from '@/utils/validate';
  import * as api from '@/api/base-data/product/info';
  import * as propertyApi from '@/api/base-data/product/property';
  import { multiplePageMix } from '@/mixins/multiplePageMix';
  import JImgUpload from '/@/components/JImgUpload/src/JImgUpload.vue';
  import UnitSelector from '@/components/Selector/src/UnitSelector.vue';
  import { getCartesian } from '@/utils/cartesian';
  import BatchSetting from '@/views/base-data/product/info/batchSetting.vue';
  import { generateCode } from '@/api/components';
  import ShopSelector from '@/components/Selector/src/ShopSelector.vue';
  import SelectGenSpec from '@/views/base-data/product/info/selectGenSpec.vue';

  export default defineComponent({
    name: 'ModifyProduct',
    // 使用组件
    components: {
      SelectGenSpec,
      ShopSelector,
      BatchSetting,
      UnitSelector,
      JImgUpload,
    },
    mixins: [multiplePageMix],
    props: {
      id: {
        type: String,
        default: '',
      },
      categoryTypes: {
        type: String,
        required: true,
      },
    },
    setup() {
      return {
        h,
        PlusOutlined,
        DeleteOutlined,
        EditOutlined,
        InfoCircleOutlined,
      };
    },
    data() {
      return {
        // 是否可见
        visible: false,
        // 是否显示加载框
        loading: false,
        // 表单数据
        formData: {},
        productType: undefined,
        productBundles: [],
        modelorList: [],
        // 表单校验规则
        rules: {
          code: [
            { required: true, message: '请输入编号' },
            {
              validator: validCode,
              message: '编号必须由字母、数字、"-"_.""组成，长度不能超过20位',
            },
          ],
          name: [{ required: true, message: '请输入名称' }],
          skuCode: [{ required: true, message: '请输入SKU编号' }],
          categoryId: [{ required: true, message: '请选择分类' }],
          brandId: [{ required: true, message: '请选择品牌' }],
          weight: [
            {
              validator: (rule, value) => {
                if (!this.$utils.isEmpty(value)) {
                  if (!this.$utils.isFloat(value)) {
                    return Promise.reject('重量（kg）必须为数字');
                  }
                  if (!this.$utils.isFloatGeZero(value)) {
                    return Promise.reject('重量（kg）不允许小于0');
                  }
                  if (!this.$utils.isNumberPrecision(value, 2)) {
                    return Promise.reject('重量（kg）最多允许2位小数');
                  }
                }

                return Promise.resolve();
              },
            },
          ],
          volume: [
            {
              validator: (rule, value) => {
                if (!this.$utils.isEmpty(value)) {
                  if (!this.$utils.isFloat(value)) {
                    return Promise.reject('体积（cm³）必须为数字');
                  }
                  if (!this.$utils.isFloatGeZero(value)) {
                    return Promise.reject('体积（cm³）不允许小于0');
                  }
                  if (!this.$utils.isNumberPrecision(value, 2)) {
                    return Promise.reject('体积（cm³）最多允许2位小数');
                  }
                }

                return Promise.resolve();
              },
            },
          ],
          taxRate: [
            { required: true, message: '请输入进项税率（%）' },
            {
              validator: (rule, value) => {
                if (!this.$utils.isEmpty(value)) {
                  if (!this.$utils.isFloat(value)) {
                    return Promise.reject('进项税率（%）必须为数字');
                  }
                  if (!this.$utils.isFloatGeZero(value)) {
                    return Promise.reject('进项税率（%）不允许小于0');
                  }
                  if (!this.$utils.isNumberPrecision(value, 2)) {
                    return Promise.reject('进项税率（%）最多允许2位小数');
                  }
                }

                return Promise.resolve();
              },
            },
          ],
          saleTaxRate: [
            { required: true, message: '请输入销项税率（%）' },
            {
              validator: (rule, value) => {
                if (!this.$utils.isEmpty(value)) {
                  if (!this.$utils.isFloat(value)) {
                    return Promise.reject('销项税率（%）必须为数字');
                  }
                  if (!this.$utils.isFloatGeZero(value)) {
                    return Promise.reject('销项税率（%）不允许小于0');
                  }
                  if (!this.$utils.isNumberPrecision(value, 2)) {
                    return Promise.reject('销项税率（%）最多允许2位小数');
                  }
                }

                return Promise.resolve();
              },
            },
          ],
          purchasePrice: [
            { required: true, message: '请输入采购价（元）' },
            {
              validator: (rule, value) => {
                if (!this.$utils.isEmpty(value)) {
                  if (!this.$utils.isFloat(value)) {
                    return Promise.reject('采购价（元）必须为数字');
                  }
                  if (!this.$utils.isFloatGeZero(value)) {
                    return Promise.reject('采购价（元）不允许小于0');
                  }
                  if (!this.$utils.isNumberPrecision(value, 2)) {
                    return Promise.reject('采购价（元）最多允许2位小数');
                  }
                }

                return Promise.resolve();
              },
            },
          ],
          salePrice: [
            { required: true, message: '请输入销售价（元）' },
            {
              validator: (rule, value) => {
                if (!this.$utils.isEmpty(value)) {
                  if (!this.$utils.isFloat(value)) {
                    return Promise.reject('销售价（元）必须为数字');
                  }
                  if (!this.$utils.isFloatGeZero(value)) {
                    return Promise.reject('销售价（元）不允许小于0');
                  }
                  if (!this.$utils.isNumberPrecision(value, 2)) {
                    return Promise.reject('销售价（元）最多允许2位小数');
                  }
                }

                return Promise.resolve();
              },
            },
          ],
          retailPrice: [
            { required: true, message: '请输入零售价（元）' },
            {
              validator: (rule, value) => {
                if (!this.$utils.isEmpty(value)) {
                  if (!this.$utils.isFloat(value)) {
                    return Promise.reject('零售价（元）必须为数字');
                  }
                  if (!this.$utils.isFloatGeZero(value)) {
                    return Promise.reject('零售价（元）不允许小于0');
                  }
                  if (!this.$utils.isNumberPrecision(value, 2)) {
                    return Promise.reject('零售价（元）最多允许2位小数');
                  }
                }

                return Promise.resolve();
              },
            },
          ],
          available: [{ required: true, message: '请选择状态' }],
        },
        // 多规格表格列
        tableColumn: [],
        // 多规格表格默认列
        defaultColumn: [
          {
            title: '规格',
            field: 'spec',
            minWidth: 240,
            slots: { default: 'spec_default' },
          },
          {
            title: 'sku编号',
            field: 'skuCode',
            minWidth: 240,
            slots: { default: 'sku_default' },
          },
          {
            title: '采购价（元）',
            field: 'purchasePrice',
            width: 120,
            type: 'price',
            slots: { default: 'price_default', header: 'setting_header' },
          },
          {
            title: '零售价（元）',
            field: 'retailPrice',
            width: 120,
            type: 'price',
            slots: { default: 'price_default', header: 'setting_header' },
          },
          {
            title: '销售价（元）',
            field: 'salePrice',
            width: 120,
            type: 'price',
            slots: { default: 'price_default', header: 'setting_header' },
          },
          {
            title: '重量（kg）',
            field: 'weight',
            width: 120,
            type: 'number',
            slots: { default: 'number_default', header: 'setting_header' },
          },
          {
            title: '体积',
            field: 'volume',
            width: 120,
            type: 'number',
            slots: { default: 'number_default', header: 'setting_header' },
          },
          {
            title: '状态',
            field: 'available',
            width: 120,
            type: 'available',
            slots: { default: 'available_default', header: 'setting_header' },
          },
          { title: '操作', width: 80, fixed: 'right', slots: { default: 'action_default' } },
        ],
      };
    },
    methods: {
      // 打开对话框
      openDialog() {
        this.visible = true;
        this.$nextTick(() => {
          // 初始化数据
          this.initFormData();
          // 查询数据
          this.loadFormData();
        });
      },
      // 关闭对话框
      closeDialog() {
        this.visible = false;
      },
      // 初始化表单数据
      initFormData() {
        this.productType = undefined;
        this.productBundles = [];
        this.formData = {};
        this.modelorList = [];
      },
      // 提交表单事件
      async submit() {
        const that = this;
        let valid = true;

        await this.$refs.form.validate().then((res) => {
          valid = res;
        });

        if (!valid) {
          return;
        }
        if (this.$enums.PRODUCT_TYPE.BUNDLE.equalsCode(this.productType)) {
          // 如果是组合商品
          if (this.$utils.isEmpty(this.productBundles)) {
            this.$msg.createError('组合商品必须包含单品数据！');
            return;
          }

          let salePrice = 0;
          let retailPrice = 0;
          for (let i = 0; i < this.productBundles.length; i++) {
            const bundleProduct = this.productBundles[i];
            if (this.$utils.isEmpty(bundleProduct.productId)) {
              this.$msg.createError('第' + (i + 1) + '行单品不能为空！');
              return;
            }

            if (this.$utils.isEmpty(bundleProduct.bundleNum)) {
              this.$msg.createError('第' + (i + 1) + '行单品包含数量不能为空！');
              return;
            }
            if (!this.$utils.isInteger(bundleProduct.bundleNum)) {
              this.$msg.createError('第' + (i + 1) + '行单品包含数量必须为整数！');
              return;
            }
            if (!this.$utils.isIntegerGtZero(bundleProduct.bundleNum)) {
              this.$msg.createError('第' + (i + 1) + '行单品包含数量必须大于0！');
              return;
            }

            if (this.$utils.isEmpty(bundleProduct.salePrice)) {
              this.$msg.createError('第' + (i + 1) + '行单品销售价（元）不能为空！');
              return;
            }
            if (!this.$utils.isFloat(bundleProduct.salePrice)) {
              this.$msg.createError('第' + (i + 1) + '行单品销售价（元）必须为数字！');
              return;
            }
            if (!this.$utils.isFloatGtZero(bundleProduct.salePrice)) {
              this.$msg.createError('第' + (i + 1) + '行单品销售价（元）必须大于0！');
              return;
            }
            if (!this.$utils.isNumberPrecision(bundleProduct.salePrice, 2)) {
              this.$msg.createError('第' + (i + 1) + '行单品销售价（元）最多允许2位小数！');
              return;
            }

            if (this.$utils.isEmpty(bundleProduct.retailPrice)) {
              this.$msg.createError('第' + (i + 1) + '行单品零售价（元）不能为空！');
              return;
            }
            if (!this.$utils.isFloat(bundleProduct.retailPrice)) {
              this.$msg.createError('第' + (i + 1) + '行单品零售价（元）必须为数字！');
              return;
            }
            if (!this.$utils.isFloatGtZero(bundleProduct.retailPrice)) {
              this.$msg.createError('第' + (i + 1) + '行单品零售价（元）必须大于0！');
              return;
            }
            if (!this.$utils.isNumberPrecision(bundleProduct.retailPrice, 2)) {
              this.$msg.createError('第' + (i + 1) + '行单品零售价（元）最多允许2位小数！');
              return;
            }

            salePrice = this.$utils.add(
              salePrice,
              this.$utils.mul(bundleProduct.bundleNum, bundleProduct.salePrice),
            );
            retailPrice = this.$utils.add(
              retailPrice,
              this.$utils.mul(bundleProduct.bundleNum, bundleProduct.retailPrice),
            );
          }

          if (!this.$utils.eq(salePrice, this.formData.salePrice)) {
            this.$msg.createError(
              '当前所有单品的【包含数量】乘以【销售价（元）】的总和为' +
                salePrice +
                '元，组合商品的销售价为' +
                this.formData.salePrice +
                '元，两个值不相等，请调整！',
            );
            return;
          }

          if (!this.$utils.eq(retailPrice, this.formData.retailPrice)) {
            this.$msg.createError(
              '当前所有单品的【包含数量】乘以【零售价（元）】的总和为' +
                retailPrice +
                '元，组合商品的零售价为' +
                this.formData.retailPrice +
                '元，两个值不相等，请调整！',
            );
            return;
          }
        }
        if (!this.$utils.isEmpty(this.modelorList)) {
          this.modelorList
            .filter((item) => item.isRequired)
            .every((item) => {
              if (that.$utils.isEmpty(item.text)) {
                that.$msg.createError(item.name + '不能为空！');
                valid = false;
                return false;
              }

              return true;
            });
        }

        if (!valid) {
          return;
        }

        const properties = this.modelorList
          .filter((item) => !this.$utils.isEmpty(item.text))
          .map((item) => {
            return {
              id: item.id,
              text: this.$utils.isArray(item.text) ? JSON.stringify(item.text) : item.text,
            };
          });

        const params = Object.assign({}, this.formData, {
          properties: properties,
          productBundles: this.productBundles,
        });
        this.loading = true;
        api
          .update(params)
          .then(() => {
            this.$msg.createSuccess('修改成功！');
            this.$emit('confirm');
            this.closeDialog();
          })
          .finally(() => {
            this.loading = false;
          });
      },
      // 查询数据
      loadFormData() {
        this.loading = true;
        api
          .get(this.id)
          .then((data) => {
            this.formData = Object.assign({}, data);
            this.selectCategory(this.formData.categoryId, this.formData);
            this.productType = this.formData.productType;
            this.productBundles = data.productBundles;
          })
          .finally(() => {
            this.loading = false;
          });
      },
      selectCategory(val, formData) {
        this.modelorList = [];
        if (!this.$utils.isEmpty(val)) {
          propertyApi.getModelorByCategory(val).then((res) => {
            const modelorList = res;
            if (formData) {
              const properties = formData.properties || [];
              modelorList.forEach((item) => {
                item.text = (properties.filter((p) => p.id === item.id)[0] || {}).text;
                if (this.$enums.COLUMN_TYPE.MULTIPLE.equalsCode(item.columnType)) {
                  item.text = this.$utils.isEmpty(item.text) ? [] : item.text.split(',');
                }
              });
            }

            modelorList
              .filter((item) => this.$utils.isEmpty(item.text))
              .forEach((item) => {
                if (this.$enums.COLUMN_TYPE.MULTIPLE.equalsCode(item.columnType)) {
                  item.text = [];
                } else {
                  item.text = '';
                }
              });

            this.modelorList = modelorList;

            this.initPropertyColumn();
          });
        }
      },
      addRow() {
        this.productBundles.push(this.emptyProduct());
      },
      emptyProduct() {
        return {
          id: this.$utils.uuid(),
          productId: '',
        };
      },
      delRow() {
        const records = this.$refs.grid.getCheckboxRecords();
        if (this.$utils.isEmpty(records)) {
          this.$msg.createError('请选择要删除的商品数据！');
          return;
        }

        this.$msg.createConfirm('是否确定删除选中的商品？').then(() => {
          this.productBundles = this.productBundles.filter((t) => {
            const tmp = records.filter((item) => item.id === t.id);
            return this.$utils.isEmpty(tmp);
          });
        });
      },
      initPropertyColumn() {
        this.tableColumn = [];
        this.tableColumn.push({ type: 'checkbox', fixed: 'left', width: 45 });
        this.modelorList
          .filter((item) => [1, 2].includes(item.columnType))
          .map((item) => item.id)
          .forEach((item) => {
            this.tableColumn.push({
              title: this.modelorList.find((p) => p.id === item)?.name,
              field: `${item}`,
              minWidth: 120,
              fixed: 'left',
              slots: { default: 'propertyValue_default' },
            });
          });
        this.tableColumn.push(...this.defaultColumn);
      },
      addSpec(genSkuCode) {
        if (!this.formData.productData) {
          this.formData.productData = [];
        }
        this.formData.productData.push({
          property: this.modelorList
            .filter((item) => [1, 2].includes(item.columnType))
            .map((item) => ({
              edit: true,
              propertyId: item.id,
              propertyItemId: null,
            })),
          available: true,
        });
        if (genSkuCode) {
          const rowIndex = this.formData.productData.length - 1;
          this.onGenerateSkuCode(this.formData.productData[rowIndex]);
        }
      },
      delSpec(rowIndex) {
        this.formData.productData.splice(rowIndex, 1);
      },
      generateSpec() {
        this.$msg.createConfirm('是否确定批量生成规格？').then(() => {
          this.formData.productData = this.formData.productData.filter((item) => item.specId);
          let sets = [];
          this.modelorList.forEach((p) => {
            sets.push(p.items.map((item) => item.id));
          });
          getCartesian(sets).forEach((item) => {
            const key = item.join(',');
            const exist = !!this.formData.productData.find(
              (item) => item.validPropertyValues === key,
            );
            if (!exist) {
              this.addSpec();
              const rowIndex = this.formData.productData.length - 1;
              item.forEach((propertyItemId, i) => {
                const row = this.formData.productData[rowIndex];
                this.propertyValueChange(i, row, propertyItemId);
              });
            }
          });
        });
      },
      // 计算售价
      calculatePrice(file) {
        // 和所有包含数量乘以售价的总和
        return this.productBundles
          .map((item) => (item[file] || 0) * (item.bundleNum || 0))
          .reduce((a, b) => a + b, 0);
      },
      onGenerateSkuCode(target, field = 'skuCode') {
        generateCode(this.$enums.GENERATE_CODE_TYPE.COMMON.code).then((res) => {
          if (target) {
            target[field] = res;
          } else {
            this.formData[field] = res;
          }
        });
      },
      onGenerateSpec(target, field = 'spec') {
        let spec = this.calculatePropertyValuesText(target.property);
        if (target) {
          target[field] = spec;
        } else {
          this.formData[field] = spec;
        }
      },
      propertyValueChange(columnIndex, row, value) {
        if (!row.property) row.property = [];
        if (!row.property[columnIndex]) row.property[columnIndex] = {};
        row.property[columnIndex].edit = true;
        row.property[columnIndex].propertyId = this.modelorList.filter((item) =>
          [1, 2].includes(item.columnType),
        )[columnIndex].id;
        row.property[columnIndex].propertyItemId = value;
        const validPropertyValues = this.calculatePropertyValues(row.property);
        const specText = this.calculatePropertyValuesText(row.property);
        if (
          validPropertyValues &&
          this.formData.productData.filter(
            (item) => item.validPropertyValues === validPropertyValues,
          ).length > 0
        ) {
          row.property[columnIndex].propertyItemId = null;
          this.$msg.createError('已存在相同规格');
          return;
        }
        row.validPropertyValues = validPropertyValues;
        row.spec = specText;
      },
      calculatePropertyValues(property) {
        if (property) {
          return this.modelorList
            .map((item) => item.id)
            .map((id) => property.find((p) => p.propertyId === id)?.propertyItemId)
            .filter((item) => item)
            .join(',');
        }
      },
      calculatePropertyValuesText(property) {
        if (property) {
          return this.modelorList
            .filter((item) => !!property.find((p) => p.propertyId === item.id))
            .flatMap((item) => item.items)
            .filter((item) => !!property.find((p) => p.propertyItemId === item.id))
            .map((item) => item.name)
            .filter((item) => item)
            .join(',');
        }
      },
      batchSettingConfirm(field, value) {
        if (field) {
          this.formData?.productData?.forEach((item) => {
            item[field] = value;
          });
        }
      },
      batchDeleteSpec() {
        const records = this.$refs.specGrid.getCheckboxRecords();
        if (this.$utils.isEmpty(records)) {
          this.$msg.createError('请选择要删除的规格数据！');
          return;
        }

        this.$msg.createConfirm('是否确定删除选中的规格数据？').then(() => {
          this.formData.productData = this.formData.productData.filter((t) => {
            const tmp = records.filter((item) => item.id === t.id);
            return this.$utils.isEmpty(tmp);
          });
        });
      },
      selectGenerateSpec() {
        this.$refs.selectGenSpecRef.openDialog();
      },
      onSelectGenSpec(sets) {
        if (this.$utils.isEmpty(sets)) {
          this.$msg.createError('请选择规格');
          return;
        }
        getCartesian(sets).forEach((item, index) => {
          this.addSpec();
          item.forEach((propertyItemId, i) => {
            this.propertyValueChange(i, this.formData.productData[index], propertyItemId);
          });
        });
      },
    },
  });
</script>
